package edu.hunau.cxb18.spring.aop.config.advice;

import org.aopalliance.aop.Advice;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.springframework.aop.Advisor;

import java.util.Arrays;

/**
 * 使用一个普通的类定义通知
 *
 * @author hb
 * @create 2020-03-16 10:30
 */
public class MyAdvice {

    /**
     * 希望该功能在目标方法执行之前执行
     */
    public void before() {
        System.out.println("\t【额外功能】:检查权限。。。");
    }

    /**
     * 后置通知
     *
     * @param j   JoinPoint是可有可无的参数，封装了目标对象和目标方法的信息
     * @param rvt 声明返回结果，必须在配置文件中声明该返回结果。
     */
    public void afterReturning(JoinPoint j, Object rvt) {
        System.out.println("\t【额外功能】:记录信息 ");
        System.out.println("目标对象：" + j.getTarget());
        Signature signature = j.getSignature();//获得目标方法的方法签名
        System.out.println("目标方法：" + signature.getName());
        System.out.println("返回结果：" + rvt);
        System.out.println("目标参数：" + Arrays.toString(j.getArgs()) + "\n\n");
    }

    public void after(JoinPoint j) {
        System.out.println("\t【额外功能】:后置通知 ");
        System.out.println("目标对象：" + j.getTarget() + "\t");
    }

    /**
     * 异常通知
     *
     * @param j
     * @param ex 表示目标方法抛出的异常，必须在配置文件中使用throwing=“参数名”进行配置
     */
    public void hasException(JoinPoint j, Exception ex) {
        System.out.println("\t【额外功能】:异常通知 ");
        System.out.println("\t目标对象：" + j.getTarget());
        System.out.println("\t异常信息：" + ex.getMessage() + "\n");

    }

    /**
     * 表示环绕通知：开启和关闭事务
     *
     * @param jp 该参数由spring容器进行注入，通过该参数可以执行目标方法
     * @return  必须将结果返回，其他方法获得当前目标方法的返回值
     */
    public Object around(ProceedingJoinPoint jp) throws Throwable {
        System.out.println("\t【额外功能】:开启事务 ");//可以使用前置通知
        Object result = null;
        try {
            result = jp.proceed();
        } catch (Throwable e) {
            //e.printStackTrace();//可以使用异常通知
            throw e;
        } finally {
            System.out.println("\t【额外功能】:关闭事务 ");//可以使用后置通知
        }
        return result;
    }
}
